/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						       shared_file.h

	$Header: /game/shared_file.h $

	$NoKeywords: $

 ************************************************************************/

#ifndef SHARED_FILE_H_INCLUDED
#define SHARED_FILE_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <stdio.h>
#include <streambuf>

#include "abstract_file.h"
#include "counted_ptr.h"
#include "data_lock.h"
#include "owned_ptr.h"
#include "sized_int_types.h"
#include "shared_file_ptr.h"

// ----------------------------------------------------------
// a file which is designed to be shared between several objects or threads
// ------------------------------------------------------------

class t_shared_file : public t_counted_object
{
public:

	t_shared_file();
	t_shared_file( std::string filename, std::string mode , t_derived_file_systems file_system = k_standard_c_file_sys);

	virtual ~t_shared_file();
	
	t_abstract_file*			get_abstract_file() const;	
	t_data_lock&				get_data_lock();
	std::string					get_filename() const;

	void						lock();
	void						unlock();

protected:

	std::string m_filename;
	t_data_lock m_data_lock;

//private:

	t_owned_ptr<t_abstract_file>	m_file_ptr;
	t_derived_file_systems			m_file_system;
};

inline t_data_lock& t_shared_file::get_data_lock() 
{
	return m_data_lock;
}

inline t_abstract_file* t_shared_file::get_abstract_file() const
{
	return m_file_ptr.get();
}

inline std::string t_shared_file::get_filename() const
{
	return m_filename;
}

inline void t_shared_file::lock()
{
	m_data_lock.lock();
}

inline void t_shared_file::unlock() 
{
	m_data_lock.unlock();
}

// ----------------------------------------------------------
// streambuf which uses t_shared_file
// ----------------------------------------------------------
class t_shared_file_buffer : public std::streambuf
{
public:
	t_shared_file_buffer( t_shared_file* file );
protected:

    virtual pos_type	seekoff(off_type offset, std::ios_base::seekdir base_offset,
								std::ios_base::openmode which = std::ios_base::in );
    virtual pos_type	seekpos(pos_type position,
								std::ios_base::openmode which = std::ios_base::in );
    virtual int_type	underflow();
    
	t_shared_file_ptr m_file;
	t_uint32          m_file_position;
	t_uint32		  m_file_size;
	t_owned_ptr<char> m_buffer;
	bool			  m_use_windows_file;
};

// ----------------------------------------------------------
// a specialized shared resource file class for the resource editor.
// ----------------------------------------------------------
class t_resource_shared_file : public t_shared_file
{
public:

	t_resource_shared_file();
	t_resource_shared_file( std::string filename, std::string mode , t_derived_file_systems file_system = k_standard_c_file_sys);
	
	bool open( const char *filename, const char *mode , t_derived_file_systems file_system = k_standard_c_file_sys);
	bool close( );

	bool is_open();
};

typedef t_counted_ptr <t_resource_shared_file> t_resource_shared_file_ptr;

#endif // SHARED_FILE_H_INCLUDED